package com.sukaiyi.generator.config.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import java.io.Serializable;
import java.util.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class StructTemplateTreeNode implements Serializable, MutableTreeNode {
    private String name;
    private String content;
    private TplType type;
    private StructTemplateTreeNode parent;
    private List<StructTemplateTreeNode> children;
    private Object userObject;

    @Override
    public void insert(MutableTreeNode child, int index) {
        if (child instanceof StructTemplateTreeNode) {
            child.setParent(this);
            children.add(index, (StructTemplateTreeNode) child);
        }
    }

    @Override
    public void remove(int index) {
        MutableTreeNode child = children.remove(index);
        if (child != null) {
            child.setParent(null);
        }
    }

    @Override
    public void remove(MutableTreeNode node) {
        if (node instanceof StructTemplateTreeNode) {
            children.remove(node);
            node.setParent(null);
        }
    }

    @Override
    public void setUserObject(Object object) {
        userObject = object;
    }

    @Override
    public void removeFromParent() {
        MutableTreeNode parent = (MutableTreeNode) getParent();
        if (parent != null) {
            parent.remove(this);
        }
    }

    @Override
    public void setParent(MutableTreeNode newParent) {
        if (newParent instanceof StructTemplateTreeNode) {
            this.parent = (StructTemplateTreeNode) newParent;
        }
    }

    @Override
    public TreeNode getChildAt(int childIndex) {
        return Optional.ofNullable(children).map(e -> e.get(childIndex)).orElse(null);
    }

    @Override
    public int getChildCount() {
        return Optional.ofNullable(children).map(List::size).orElse(0);
    }

    @Override
    public TreeNode getParent() {
        return parent;
    }

    @Override
    public int getIndex(TreeNode node) {
        if (node instanceof StructTemplateTreeNode) {
            return Optional.ofNullable(children).map(e -> e.indexOf(node)).orElse(-1);
        }
        return -1;
    }

    @Override
    public boolean getAllowsChildren() {
        return type == TplType.MODULE;
    }

    @Override
    public boolean isLeaf() {
        return type == TplType.TEMPLATE;
    }

    @Override
    public Enumeration children() {
        Iterator<StructTemplateTreeNode> it = Optional.ofNullable(children).map(List::iterator).orElse(Collections.emptyIterator());
        return new Enumeration() {
            @Override
            public boolean hasMoreElements() {
                return it.hasNext();
            }

            @Override
            public Object nextElement() {
                return it.next();
            }
        };
    }
}
